//Christian Larco RGB code

//------------ Libraries used in the program -------------------
#include <avr/io.h>
#include <util/delay.h>
//--------------------------------------------------------------

//------------ Define Variables --------------------------------
#define F_CPU 8000000UL 		// 8 MHz
int flag = 0;					// Break out color loop flag
//--------------------------------------------------------------


//------------ Initialization of different variables -----------
void init()
{
	DDRB = 0xFF;			// Direction of B output
	DDRD = 0xFF;			// Direction of D output
	
	TCCR0A = 0xA3;			// PWM sets, fast PWMs
	TCCR1A = 0xA3;
	TCCR2A = 0xA3;
	
	OCR0A = OCR1A = OCR2A = 255; //Set timer period

	TCCR0B = 0x09;			// Pre-scaling not set for all
	TCCR1B = 0x19;
	TCCR2B = 0x09;
	
	OCR0B = OCR1B = OCR2B = 0;	//set duty cycle equal to 0
}
//--------------------------------------------------------------

//----------------- Code for the main body -------------------------
int main(void)
{
	init();			// Initialize everything
	while(1)
	{
		hueCHANGE();	// Change colors
		hueMERGE();	// Merge colors
	}
}
//------------------------------------------------------------------




//------------------------Code to merge the hue -------------------------
void hueMERGE()
{
	OCR0B = 230;		// Reset duty cycle to 90% to allow for merging

	// FOR COLOR 1 AND COLOR 2
	while(OCR0B > 0)
	{
		OCR0B--;		// Decrease color 1
		OCR1B++;		// Increase color 2
	}
	_delay_ms(15);		// Set a delay for easier viewing
	// FOR COLOR 2 AND COLOR 3
	while(OCR1B > 0)
	{
		OCR1B--;		// Decrease color 2
		OCR2B++;		// Increase color 3
	}
	_delay_ms(15);		// Set a delay for easier viewing
	// FOR COLOR 3 AND COLOR 1
	while(OCR2B > 0)
	{
		OCR2B--;		// Decrease color 3
		OCR0B++;		// Increase color 1
	}
	_delay_ms(15);		// Set a delay for easier viewing
}
//------------------------------------------------------------------

//---------- Code to change the color of the LED ---------------
void hueCHANGE()
{
	flag = 1;				// Break out of each color loop when finished										// FOR COLOR 1
	while(flag)
	{
		OCR0A--;			// Decrement the period
		if (OCR0A < 26)
		{
			OCR0A = 255;	// Reset period
			OCR0B++;		// increment the duty cycle
		}
		if (OCR0B > 230)	// Ensure a 90% maximum duty cycle
		{
			OCR0B = 0;		// Color Reset
			flag = 0;
		}
	}
	_delay_us(240);			// Set a delay for easier viewing
	flag = 1;				// Break out of each color loop when finished
	// FOR COLOR 2
	while(flag)
	{
		OCR1A--;			// Decrement the period
		if (OCR1A < 26)		// Disallow the period to dip too low
		{
			OCR1A = 255;	// Reset the period when this occurs
			OCR1B++;		// While also incrementing the duty cycle
		}
		if (OCR1B > 230)		// Ensure a 90% maximum duty cycle
		{
			OCR1B = 0;		// Reset the color
			flag = 0;
		}
	}
	_delay_us(240);			// Set a delay for easier viewing
	flag = 1;				// Break out of each color loop when finished
	// FOR COLOR 3
	while(flag)
	{
		OCR2A--;
		if (OCR2A < 26)
		{
			OCR2A = 255;
			OCR2B++;
		}
		if (OCR2B > 230)
		{
			OCR2B = 0;
			flag = 0;
		}
	}
	_delay_us(250);			// Set a delay for easier viewing
}
//-----------------------------------------------------------------------
